import cv2
import numpy as np



class Gaussian_filter:
    
    def __init__(self, K_size, sigma):
        
        '''
        定义高斯滤波器类，
        根据输入滤波核大小和方差构建滤波核，
        读取图像后高斯滤波处理
        利用compare函数将原图，手动高斯滤波结果，opencv库函数处理结果对比可视化输出
        '''
        
        self.K_size=K_size
        self.sigma =sigma
        self.kernel=np.zeros((K_size,K_size),dtype=float)
        self.img=[]
        self.new_img=[]
        
    def kernel_creat(self):
        
        '''构建滤波核并可视化输出到终端'''
        
        R=self.K_size//2
        for y in range(-R,-R+self.K_size):
            for x in range(-R,-R+self.K_size):
                self.kernel[y+R,x+R]=np.exp(-(x**2+y**2)/(2*self.sigma**2))
        self.kernel/=self.kernel.sum()
        print(f"该高斯滤波器的滤波核为：\n{self.kernel}")
        
        
    def img_read(self,img_path):
        
        '''读取图片'''
        
        self.img = cv2.imread(img_path)
        
        return self.img
    
    def operation(self):
        
        '''高斯滤波算法实现'''
        
        [H,W,C]= self.img.shape
        R=self.K_size//2
        temp=np.zeros((2*R+H,2*R+W,C),dtype=float)
        temp[R:R+H,R:R+W,:]=self.img.copy().astype(float)
        self.new_img=temp.copy().astype(float)
        for y in range(H):
            for x in range(W):
                for c in range(C):
                    self.new_img[y+R,x+R,c]=np.sum(self.kernel*temp[y:y+self.K_size,x:x+self.K_size,c])
        self.new_img=np.clip(self.new_img.astype(np.uint8)[R:R+H,R:R+W,:],0,255)
        return self.new_img
        
    def cv_operation(self):
        '''利用opencv库函数滤波'''
        cvnewimg=cv2.GaussianBlur(self.img,(self.K_size,self.K_size),self.sigma) 
        return cvnewimg
    
    def img_compare(self):
        '''对比自行设计算法处理与opencv处理结果区别，并可视化输出'''
        compare = np.hstack([self.img , self.new_img , self.cv_operation()])
        cv2.namedWindow('compare',cv2.WINDOW_NORMAL)
        cv2.imshow('compare',compare)
        cv2.waitKey(0)
        return compare



    
if __name__ == "__main__":     
    '''对比不同K_size和sigma，手动调下面就好了qwq
    总共出来三张图，第一张G1输出，第二张G2输出
    第三场G1，G2对比输出'''
    G1=Gaussian_filter(K_size=5,sigma=1.3)
    G1.kernel_creat()
    G1.img_read('1.jpg')
    G1.operation()
    
    G2=Gaussian_filter(K_size=3,sigma=2.6)
    G2.kernel_creat()
    G2.img_read('YOIMIYA.jpg')
    G2.operation()
    
    compare=np.vstack([G1.img_compare(),G2.img_compare()])
    cv2.namedWindow('compare',cv2.WINDOW_NORMAL)
    cv2.imshow('compare',compare)
    cv2.waitKey(0)
    cv2.imwrite('compare.jpg',compare)

